import socket
from threading import Thread

class UDPCommunicator(Thread):
    def __init__(self, host=None, port=None, timeout=None):
        super().__init__()
        """
        初始化UDP通信对象
        :param host: 绑定的主机地址（服务端需要设置）
        :param port: 绑定的端口号（服务端需要设置）
        :param timeout: 接收超时时间（秒）
        """
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

        self.recvdata = 0

        if timeout is not None:
            self.sock.settimeout(timeout)

        if host is not None and port is not None:
            self.sock.bind((host, port))

    def send(self, data, host, port):
        """
        发送数据到指定地址
        :param data: 要发送的字节数据（bytes）
        :param host: 目标主机地址
        :param port: 目标端口号
        """
        self.sock.sendto(data, (host, port))

    def receive(self, buffer_size=4096):
        """
        接收数据
        :param buffer_size: 接收缓冲区大小
        :return: (接收到的数据bytes, 发送方地址tuple) 超时返回(None, None)
        """
        try:
            data, addr = self.sock.recvfrom(buffer_size)
            return data, addr
        except socket.timeout:
            return None, None
        except Exception as e:
            print(f"接收错误: {str(e)}")
            return None, None

    def close(self):
        """关闭socket连接"""
        self.sock.close()

    def run(self):
        while True:
            data, addr = self.receive()
            self.recvdata = data

# # 使用示例 - 服务端
# def run_server():
#     server = UDPCommunicator(host='0.0.0.0', port=9999, timeout=1)
#     print("服务端已启动，等待数据...")
#
#     while True:
#         data, addr = server.receive()
#         if data:
#             print(f"收到来自 {addr} 的消息: {data.decode()}")
#             server.send(b"Message received", addr[0], addr[1])
#
#
# # 使用示例 - 客户端
# def run_client():
#     client = UDPCommunicator()
#     message = "Hello UDP Server!".encode()
#
#     # 发送消息
#     client.send(message, '127.0.0.1', 9999)
#     print("已发送消息，等待回复...")
#
#     # 接收回复
#     response, addr = client.receive()
#     if response:
#         print(f"收到来自 {addr} 的回复: {response.decode()}")
#
#     client.close()